using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;

namespace cmd
{
    [AssetList]
    public class LevelLayerDataSO : SerializedScriptableObject
    {
        [field: OdinSerialize]
        public LevelLayerData LevelLayerData { get; protected set; } = new();

        [field: SerializeField]
        [field: LabelText("场景ID"), PropertyOrder(-10)]
        public string Id { get; protected set; }

        [field: SerializeField]
        [field: LabelText("场景名称"), PropertyOrder(-11)]
        public string Name { get; protected set; }

        [Button(ButtonSizes.Medium), PropertySpace(10)]
        private void SetLevelLayerNameAndId()
        {
            // 提取name开头的数字作为Id
            var firstDigitIndex = name.IndexOfAny(
                new[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }
            );
            if (firstDigitIndex >= 0)
            {
                var lastDigitIndex = firstDigitIndex;
                while (lastDigitIndex < name.Length && char.IsDigit(name[lastDigitIndex]))
                {
                    lastDigitIndex++;
                }
                var idStr = name[0..lastDigitIndex];
                Id = idStr;
                Name = name[lastDigitIndex..].TrimStart('_', ' ');
            }

            LevelDataManager.CheckDuplicateLevelLayerIds(false);
        }
    }

    public class LevelLayerData
    {
        #region 数据
        [field: SerializeField]
        [field: ListDrawerSettings(
            ShowIndexLabels = true,
            NumberOfItemsPerPage = 5,
            CustomAddFunction = nameof(CustomAddFunction)
        )]
        [field: Title("预分配")]
        [field: LabelText("场景内预分配可拾取物品的列表")]
        public List<PickableItemInLevelConfiguration> PickableItemList { get; protected set; } =
            new();

        private PickableItemInLevelConfiguration CustomAddFunction() =>
            new(volume: 1) { IsOverrideVolume = false, IsOverrideSpawnHeight = true };

        [field: SerializeField, Space(10)]
        [field: Title("随机分配")]
        [field: LabelText("随机生成数量")]
        [field: PropertyTooltip("指定要从随机生成表中抽选多少个物体生成")]
        public int RandomGenerateCount { get; protected set; }

        [OdinSerialize]
        [ToggleGroup(nameof(IsOverrideRandomItemGenerate))]
        [LabelText("是否覆盖随机生成物品配置")]
        [PropertyTooltip("如果启用，将覆盖关卡统一的配置")]
        public bool IsOverrideRandomItemGenerate { get; protected set; } = false;

        [field: SerializeField, HideLabel]
        [field: ToggleGroup(nameof(IsOverrideRandomItemGenerate))]
        [field: LabelText("随机生成物品配置")]
        public RandomItemGenerateData RandomItemGenerateDataOverride { get; protected set; } =
            new(new());

        #endregion

        #region 方法
        /// <summary>
        /// 获取场景里最终生成的所有物品的DTO列表
        /// </summary>
        /// <returns>所有物品的DTO列表</returns>
        [Button(ButtonSizes.Medium), PropertySpace(10)]
        [TitleGroup("测试方法")]
        public List<PickableItemDataDTO> GetAllPickableItemDTOs(
            RandomItemGenerateData? randomItemGenerateData = null
        )
        {
            var result = new List<PickableItemDataDTO>();

            // 添加预分配的物品
            foreach (var config in PickableItemList)
            {
                result.Add(config.GetPickableItemDataDTO());
            }

            // 添加随机生成的物品
            var randomItems = IsOverrideRandomItemGenerate
                ? RandomItemGenerateDataOverride.GenerateRandomItems(RandomGenerateCount)
                : randomItemGenerateData?.GenerateRandomItems(RandomGenerateCount);
            if (randomItems != null)
            {
                foreach (var config in randomItems)
                {
                    result.Add(config.GetPickableItemDataDTO());
                }
            }

            return result;
        }

        #endregion

        [Serializable, Indent(-1)]
        public readonly struct PickableItemInLevelConfiguration
        {
            public enum PickableItemInLevelConfigMethod
            {
                UseSOSimple,
                UseSOComplete,
                UseInline
            }

            [OdinSerialize, LabelText("配置方式"), EnumToggleButtons, PropertyOrder(-10)]
            public PickableItemInLevelConfigMethod ConfigMethod { get; init; }

            [field: SerializeField, LabelText("物品数据SO"), PropertyOrder(-5)]
            [field: ShowIf(
                nameof(ConfigMethod),
                Condition = "@ConfigMethod == PickableItemInLevelConfigMethod.UseSOSimple || ConfigMethod == PickableItemInLevelConfigMethod.UseSOComplete"
            )]
            // [field: AssetList]
            public PickableItemDataModelSO PickableItemDataSO { get; init; }

            #region 简单使用配置
            [OdinSerialize, LabelText("是否覆盖体积")]
            [ShowIfGroup(
                nameof(PickableItemInLevelConfigMethod.UseSOSimple),
                Condition = nameof(ConfigMethod),
                Value = PickableItemInLevelConfigMethod.UseSOSimple
            )]
            [ToggleGroup("UseSOSimple/IsOverrideVolume")]
            public bool IsOverrideVolume { get; init; }

            [field: SerializeField, LabelText("体积")]
            [field: ShowIfGroup(
                nameof(PickableItemInLevelConfigMethod.UseSOSimple),
                Condition = nameof(ConfigMethod),
                Value = PickableItemInLevelConfigMethod.UseSOSimple
            )]
            [field: ToggleGroup("UseSOSimple/IsOverrideVolume")]
            [field: Min(0)]
            public float Volume { get; init; }

            [OdinSerialize, LabelText("是否覆盖生成高度")]
            [ShowIfGroup(
                nameof(PickableItemInLevelConfigMethod.UseSOSimple),
                Condition = nameof(ConfigMethod),
                Value = PickableItemInLevelConfigMethod.UseSOSimple
            )]
            [ToggleGroup("UseSOSimple/IsOverrideSpawnHeight")]
            public bool IsOverrideSpawnHeight { get; init; }

            [field: SerializeField, LabelText("生成高度(百分比)")]
            [field: ShowIfGroup(
                nameof(PickableItemInLevelConfigMethod.UseSOSimple),
                Condition = nameof(ConfigMethod),
                Value = PickableItemInLevelConfigMethod.UseSOSimple
            )]
            [field: ToggleGroup("UseSOSimple/IsOverrideSpawnHeight")]
            [field: Range(0, 100)]
            public float SpawnHeight { get; init; }

            private PickableItemDataDTO GetSimpleUseCasePickableItemDataDTO()
            {
                var overrideData = new PickableItemDataOverride
                {
                    IsOverrideVolume = IsOverrideVolume,
                    VolumeOverride = IsOverrideVolume ? new FloatRange(Volume) : new FloatRange(0),
                    IsOverrideSpawnRange = IsOverrideSpawnHeight,
                    SpawnRangeOverride = IsOverrideSpawnHeight
                        ? new FloatRange(SpawnHeight)
                        : new FloatRange(0)
                };

                return PickableItemDataSO.PickableItemDataModel.GetPickableItemDataDTO(
                    overrideData
                );
            }

            #endregion

            #region 完整使用配置
            [field: SerializeField, LabelText("物品数据覆盖")]
            [field: ShowIfGroup(
                nameof(PickableItemInLevelConfigMethod.UseSOComplete),
                Condition = nameof(ConfigMethod),
                Value = PickableItemInLevelConfigMethod.UseSOComplete
            )]
            public PickableItemDataOverride PickableItemDataOverride { get; init; }
            #endregion

            #region 内联配置
            [field: SerializeField, LabelText("物品数据")]
            [field: ShowIfGroup(
                nameof(PickableItemInLevelConfigMethod.UseInline),
                Condition = nameof(ConfigMethod),
                Value = PickableItemInLevelConfigMethod.UseInline
            )]
            public PickableItemDataModel PickableItemData { get; init; }
            #endregion

            public PickableItemDataDTO GetPickableItemDataDTO() =>
                ConfigMethod switch
                {
                    PickableItemInLevelConfigMethod.UseSOSimple
                        => GetSimpleUseCasePickableItemDataDTO(),
                    PickableItemInLevelConfigMethod.UseSOComplete
                        => PickableItemDataSO.PickableItemDataModel.GetPickableItemDataDTO(
                            PickableItemDataOverride
                        ),
                    PickableItemInLevelConfigMethod.UseInline
                        => PickableItemData.GetPickableItemDataDTO(),
                    _ => throw new ArgumentException($"不支持的配置方式: {ConfigMethod}")
                };

            #region 构造函数
            public PickableItemInLevelConfiguration(
                PickableItemInLevelConfigMethod configMethod =
                    PickableItemInLevelConfigMethod.UseSOSimple,
                PickableItemDataModelSO pickableItemDataSO = null,
                float volume = 1,
                float spawnHeight = 50,
                PickableItemDataOverride? pickableItemDataOverride = null,
                PickableItemDataModel pickableItemData = null
            )
            {
                ConfigMethod = configMethod;
                PickableItemDataSO = pickableItemDataSO;
                Volume = volume;
                SpawnHeight = spawnHeight;
                PickableItemDataOverride =
                    pickableItemDataOverride ?? new PickableItemDataOverride();
                PickableItemData = pickableItemData;

                IsOverrideVolume = false;
                IsOverrideSpawnHeight = true;
            }
            #endregion
        }
    }
}
